package com.example.order.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.example.order.comment.OrderNumber;
import com.example.order.config.ServiceResponse;
import com.example.order.config.TableServerResponse;
import com.example.order.mapper.OrderMapper;
import com.example.order.service.IOrderService;
import com.example.order.service.OrderEsSearch;
import com.example.order.service.OrderMybatisService;
import com.example.order.service.RedisService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import pojo.Order;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class OderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    OrderEsSearch orderEsSearch;

    @Autowired
    private OrderMybatisService orderMybatisService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private OrderNumber orderNumber;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IOrderService orderService;

    @Override
    public Map<String, Object> createorder(String userId, Order order) {

        order.setUserId(userId);
        Map<String, Object> map = new HashMap<>();
        System.out.println("生成订单");
        //设置订单id
        String replace = UUID.randomUUID().toString().replace("-", "");
        order.setOrderId(replace);
        //设置订单状态
        order.setOrderStatus("待支付");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //设置订单创建时间
        order.setOrderCreateTime(format.format(new Date()));
        //设置订单编号
        order.setOrderNumber(orderNumber.getOrderNos());
        int insert = orderMybatisService.createorder(order);
        if (insert > 0) {
            Integer integer = orderMapper.updateParkingStatus(order.getParkingId());
            if (integer > 0) {
                rabbitTemplate.convertAndSend("es.order.option"
                        , order.getOrderNumber() + "-create");
                System.out.println("订单创建成功");
                map.put("code", 200);
                map.put("msg", "创建订单成功");
            }
        } else {
            map.put("code", -200);
            map.put("msg", "创建订单失败！请稍后再试");
        }
        return map;
    }

//    @Override
//    @RabbitListener(queuesToDeclare = @Queue(DelayConfig.DELAY_PROCESS_QUEUE_NAME))
//    public void updateOrderStatus(String orderNumber) {
//        if (orderNumber != null) {
//            Integer integer = orderMapper.updateByOrderNumber(orderNumber);
//            if (integer > 0) {
//                sout
//                log.info("编号为" + orderNumber + "的订单失效");
//                return;
//            }
//        }
//    }

    /**
     * 后台查询所有订单
     *
     *
     * @param userId
     * @param page
     * @param limits
     * @return
     */
    @Override
    public TableServerResponse getOrders(String userId, Integer page, Integer limits) {
//        //开启分页查询
        PageHelper.startPage(page, limits);
        List<Order> list = orderMapper.getOrders(userId);
        String addressInfo = "";
        for (Order o : list) {
            addressInfo = o.getProvinceName() + o.getCityName() + o.getAreaName() + o.getStreetName();
            o.setAddressInfo(addressInfo);
        }
        //将查询出的所有数据封装到分页实体类中
        PageInfo pageInfo = new PageInfo(list);
        return TableServerResponse.createSuccess(0, list, pageInfo.getTotal());
    }

    @Override
    public ServiceResponse pay(String orderNo) {
        Order order = orderMapper.pay(orderNo);
        if (order.getOrderStatus().equals("已支付")) {
            return ServiceResponse.createError("支付宝订单生成失败");
        }
        // (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
        // 需保证商户系统端不能重复，建议通过数据库sequence生成，
        String outTradeNo = orderNo + "";
        // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
        String subject = "共享车位当面付扫码消费";
        // (必填) 订单总金额，单位为元，不能超过1亿元
        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
        String totalAmount = order.getMoney() + "";
        // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
        String undiscountableAmount = "0";
        // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
        // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
        String sellerId = "";
        // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
        String body = "购买商品共" + order.getMoney() + "元";
        // 商户操作员编号，添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";
        // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
        String storeId = "test_store_id";
        // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088100200300400500");
        // 支付超时，定义为120分钟
        String timeoutExpress = "120m";
        // 商品明细列表，需填写购买商品详细信息，
//        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
//        // 创建一个商品信息，参数含义分别为商品id（使用国标）、名称、单价（单位为分）、数量，如果需要添加商品类别，详见GoodsDetail
//        GoodsDetail goods1 = GoodsDetail.newInstance("goods_id001", "xxx小面包", 1000, 1);
//        // 创建好一个商品后添加至商品明细列表
//        goodsDetailList.add(goods1);
        // 继续创建并添加第一条商品信息，用户购买的产品为“黑人牙刷”，单价为5.00元，购买了两件
//        GoodsDetail goods2 = GoodsDetail.newInstance("goods_id002", "xxx牙刷", 500, 2);
//        goodsDetailList.add(goods2);
        // 创建扫码支付请求builder，设置请求参数
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject).setTotalAmount(totalAmount).setOutTradeNo(outTradeNo)
                .setUndiscountableAmount(undiscountableAmount).setSellerId(sellerId).setBody(body)
                .setOperatorId(operatorId).setStoreId(storeId).setExtendParams(extendParams)
                .setTimeoutExpress(timeoutExpress)
                .setNotifyUrl("http://3i3a9f.natappfree.cc/order/alipay_callback.do");//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
//                .setGoodsDetailList(goodsDetailList);
        //加载支付宝配置文件
        Configs.init("zfbinfo.properties");
        //提供支付宝的交易接口
        AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                System.out.println("支付宝预下单成功: )");
                AlipayTradePrecreateResponse response = result.getResponse();
                Map<Object, Object> map = new HashMap<>();
                map.put("orderNo", orderNo);
                map.put("qrPath", response.getQrCode());
                map.put("totalAmount", order.getMoney());
                return ServiceResponse.createSuccess(map);
            case FAILED:
                System.out.println("支付宝预下单失败!!!");
                return ServiceResponse.createError("支付宝预下单失败!!!");
            case UNKNOWN:
                System.out.println("系统异常，预下单状态未知!!!");
                return ServiceResponse.createError("系统异常，预下单状态未知!!!");
            default:
                System.out.println("不支持的交易状态，交易返回异常!!!");
                return ServiceResponse.createError("不支持的交易状态，交易返回异常!!!");
        }
    }

    @Override
    public ServiceResponse alipayCallback(Map<String, String> params) {
        //1.判断交易状态是否成功
        String trade_status = params.get("trade_status");
        if (!trade_status.equals("TRADE_SUCCESS")) {//如果交易状态不为TRADE_SUCCESS就表示交易失败
            return ServiceResponse.createError();
        }
        //2.把数据库中订单的交易状态改为20
        //取出订单编号
        String out_trade_no = params.get("out_trade_no");
        System.out.println(out_trade_no);
        Integer result = orderMapper.updateStatusByOrderNo(out_trade_no);
        if (result > 0) {
            //更新es
            rabbitTemplate.convertAndSend("es.order.option"
                    , out_trade_no + "-update");
            //更新redis
            Order order = orderMapper.getOrderByOrderNumber(out_trade_no);
            redisService.set(out_trade_no, order);
            return ServiceResponse.createSuccess();
        } else {
            return ServiceResponse.createError();
        }
    }

    @Override
    public ServiceResponse query_order_pay_status(String orderNo) {
        //1.根据订单编号查询订单的支付总金额
        Order order = orderMapper.pay(orderNo);
        if (StringUtils.isEmpty(order)) {
            return ServiceResponse.createError("订单不存在");
        } else {
            if ("已支付".equals(order.getOrderStatus())) {//支付成功
                return ServiceResponse.createSuccess(true);
            } else {
                return ServiceResponse.createError("支付失败");
            }
        }
    }

    @Override
    public ServiceResponse getOrderByOrderNumber(String orderNumber) {
        //先从redis缓存中查询该数据
        Order order = null;
        order = (Order) redisService.get(orderNumber);
        //如果缓存中数据为空，就去数据库中查询
        if (order == null) {
            order = orderMapper.getOrderByOrderNumber(orderNumber);
            //将查询到的数据添加到redis中
            redisService.set(orderNumber, order);
        }
        order.setAddressInfo(order.getProvinceName() + order.getCityName() + order.getAreaName() + order.getStreetName());
        return ServiceResponse.createSuccess(order);
    }

    @Override
    public ServiceResponse orderConfirm(String orderNumber) {
        //先从redis缓存中查询该数据
        Order order = null;
        order = (Order) redisService.get(orderNumber);
        //如果缓存中数据为空，就去数据库中查询
        if (order == null) {
            order = orderMapper.getOrderByOrderNumber(orderNumber);
            //将查询到的数据添加到redis中
            redisService.set(orderNumber, order);
        }
        //计算停车时长
        SimpleDateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
        Date startTime = null;
        try {
            System.err.println(order.getOrderCreateTime());
            startTime = dateFormat.parse(order.getOrderCreateTime());
            //计算该订单的费用
            //按照每小时3元收费
            long end = new Date().getTime();
            String endTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date(end));
            long start = startTime.getTime();
            //不足1小时按照1小时计算
            BigDecimal money = new BigDecimal(((end - start) / 1000 / 60 / 60) * 3);
            BigDecimal decimal = new BigDecimal(3);
            Integer integer = null;
            if (money.compareTo(decimal) == -1) {
                //更新订单信息
                integer = orderMapper.updateOrder(decimal, endTime, orderNumber);
                if (integer > 0) {
                    return ServiceResponse.createSuccess();
                }
            }
            //更新订单信息
            integer = orderMapper.updateOrder(money, endTime, orderNumber);
            if (integer > 0) {
                return ServiceResponse.createSuccess();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return ServiceResponse.createError();
    }

    @Override
    public TableServerResponse queryOrders(Order order, Integer page, Integer limits) {
//        List<Order> list = new ArrayList<>();
//        //开启分页查询
//        Page<Order> all = orderEsSearch.findAll(PageRequest.of(page, limits));
//        if (all == null) {
//            //如果es里面是空，就去数据库中查询
//            PageHelper.startPage(page, limits);
//            list = orderMapper.queryOrders(order);
//            //并将查询到的数据添加到es中
//            orderEsSearch.saveAll(list);
//        } else if(all != null) {
//            //将查询出的所有数据封装到分页实体类中
//            return TableServerResponse.createSuccess(0,all,new Long(all.getTotalPages()));
//        }
        //开启分页查询
        PageHelper.startPage(page, limits);
        List<Order> list = orderMapper.queryOrders(order);
        String addressInfo = "";
        for (Order o : list) {
            addressInfo = o.getProvinceName() + o.getCityName() + o.getAreaName() + o.getStreetName();
            o.setAddressInfo(addressInfo);
        }
        //将查询出的所有数据封装到分页实体类中
        PageInfo pageInfo = new PageInfo(list);
        return TableServerResponse.createSuccess(0, list, pageInfo.getTotal());
    }

    @Override
    public String alipayCallbacks(HttpServletRequest request) {
        System.out.println("alipay_callback.do-------------");
        //1.从request对象中取出所有的请求参数
        Map requestParams = request.getParameterMap();
        //2.遍历map集合中的数据
        Map<String, String> params = new HashMap<>();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //把request对象中的数据存放到map集合找那个
            params.put(name, valueStr);
        }
        params.forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });
        //非常重要,验证回调的正确性,是不是支付宝发的.并且呢还要避免重复通知.
//        params.remove("sign_type");
//        try {
//            //验证签
//            boolean alipayRSACheckedV2 = AlipaySignature.rsaCheckV2(params, Configs.getAlipayPublicKey(), "utf-8", Configs.getSignType());
//
//            if (!alipayRSACheckedV2) {
//                System.out.println("非法请求,验证不通过,再恶意请求我就报警找网警了");
//                return "failed";
//            }
//        } catch (AlipayApiException e) {
//            System.out.println("支付宝验证回调异常" + e);
//            return "failed";
//        }
        if (params.get("trade_status").equals("TRADE_SUCCESS")){
            return "success";
        }else{
            return "failed";
        }
//        ServiceResponse serverResopnse = orderService.alipayCallback(params);
//        if (serverResopnse.getStatus() == 0) {
//            return "success";
//        } else {
//            return "failed";
//        }
    }

    @Override
    public TableServerResponse getOrder(Integer page, Integer limits) {
        //开启分页查询
        PageHelper.startPage(page, limits);
        List<Order> list = orderMapper.getOrder();
        String addressInfo = "";
        for (Order o : list) {
            addressInfo = o.getProvinceName() + o.getCityName() + o.getAreaName() + o.getStreetName();
            o.setAddressInfo(addressInfo);
        }
        //将查询出的所有数据封装到分页实体类中
        PageInfo pageInfo = new PageInfo(list);
        return TableServerResponse.createSuccess(0, list, pageInfo.getTotal());
    }
}
